package com.dream.jump.ui.login

import android.util.Patterns
import androidx.datastore.preferences.core.Preferences
import androidx.lifecycle.*

import com.dream.jump.R
import com.dream.jump.data.DataRepository
import com.dream.jump.data.DataStoreClient
import com.dream.jump.entity.model.LoginParam
import com.dream.jump.room.TypeEntity
import com.dream.jump.util.ConstantUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class LoginViewModel @Inject constructor(private val dataRepository: DataRepository) : ViewModel() {
    private val _loginForm = MutableLiveData<LoginFormState>()
    val loginFormState: LiveData<LoginFormState> = _loginForm

    private val _loginResult = MutableLiveData<LoginResult>()
    val loginResult: LiveData<LoginResult> = _loginResult

    fun loadCacheData() {
        viewModelScope.launch {
            val userName = dataRepository.getDataStore(DataStoreClient.UserNameKey)
            val password = dataRepository.getDataStore(DataStoreClient.PasswordKey)
            if (userName.isNotEmpty() && password.isNotEmpty()) {
                _loginForm.value = LoginFormState(
                    userName, password, null, null,
                    isPasswordValid(password) && isUserNameValid(userName)
                )
            }
            val allType = dataRepository.selectAllType()
            print(allType)
        }
    }

    fun login(username: String, password: String) {
        viewModelScope.launch {
            // can be launched in a separate asynchronous job
            try {
                val loggedInUser = dataRepository.login(
                    LoginParam(
                        username, password, "com.sh3h.mobile.portal",
                        "1111111111", "222222222", "android"
                    )
                )
                DataRepository.token = loggedInUser.accessToken
                DataRepository.userId = loggedInUser.userId

                val functionArray = dataRepository.loadFunction()
                print(functionArray)
                val orderTypeArray = dataRepository.loadOrderTypes(ConstantUtil.WS_OPERATE_VIEW)
                orderTypeArray.forEach { item ->
                    dataRepository.insertOrReplaceType(
                        TypeEntity(
                            item.type, item.typeName, item.desc,
                            item.parentType, ConstantUtil.ORDER, ConstantUtil.WS_OPERATE_VIEW
                        )
                    )
                }
                print(orderTypeArray)

                val map = emptyMap<Preferences.Key<String>, String>().toMutableMap()
                map[DataStoreClient.UserNameKey] = username
                map[DataStoreClient.PasswordKey] = password
                map[DataStoreClient.AccessTokenKey] = loggedInUser.accessToken
                dataRepository.putDataStore(map)
                _loginResult.value =
                    LoginResult(success = LoggedInUserView(displayName = loggedInUser.accessToken))
            } catch (e: Exception) {
                print(e)
            }
        }
    }

    fun loginDataChanged(username: String, password: String) {
        if (!isUserNameValid(username)) {
            _loginForm.value = LoginFormState(usernameError = R.string.invalid_username)
        } else if (!isPasswordValid(password)) {
            _loginForm.value = LoginFormState(passwordError = R.string.invalid_password)
        } else {
            _loginForm.value = LoginFormState(isDataValid = true)
        }
    }

    // A placeholder username validation check
    private fun isUserNameValid(username: String): Boolean {
        return if (username.contains('@')) {
            Patterns.EMAIL_ADDRESS.matcher(username).matches()
        } else {
            username.isNotBlank()
        }
    }

    // A placeholder password validation check
    private fun isPasswordValid(password: String): Boolean {
        return password.length > 5
    }
}